package com.ikas.ai.server.module.flow.controller;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import com.ikas.ai.framework.jexl.JexlEngineFactory;
import com.ikas.ai.handle.JsonResult;
import com.ikas.ai.server.module.AbstractBean;
import com.ikas.ai.server.module.flow.dto.FlowDTO;
import com.ikas.ai.server.module.flow.model.FlowInstance;
import com.ikas.ai.server.module.flow.service.*;
import com.ikas.ai.server.module.system.model.User;
import org.apache.commons.jexl3.JexlEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 流程操作
 *
 * @Author: qi.yilai
 * @Date: 2023/1/17 16:05
 * @Version: 1.0.0
 **/
@RestController
@RequestMapping("/flow")
public class FlowController extends AbstractBean {

    @Autowired
    private FlowNodeTypeService flowNodeTypeService;

    @Autowired
    private FlowInstanceService flowInstanceService;

    @Autowired
    private FlowService flowService;

    @Autowired
    private FlowLogService flowLogService;

    @Autowired
    private FlowNodeExecService flowNodeExecService;

    /**
     * 获取节点类型
     *
     * @return
     */
    @GetMapping("/nodeTypes")
    public JsonResult nodeTypes() {
        return JsonResult.ok(flowNodeTypeService.list());
    }

    /**
     * 根据场景id获取流程
     *
     * @return
     */
    @GetMapping("/getFlowBySceneId/{sceneId}")
    public JsonResult getFlowBySceneId(@PathVariable("sceneId") Long sceneId) {
        return JsonResult.ok(flowService.getFlowBySceneId(sceneId));
    }

    /**
     * 保存和更新流程
     *
     * @param flowDTO
     * @return
     */
    @PostMapping("/saveOrUpdate")
    public JsonResult saveOrUpdate(@RequestBody FlowDTO flowDTO) {
        User user = getUser();
        flowDTO.setCreator(user.getId());
        return JsonResult.ok(flowService.saveOrUpdate(flowDTO));
    }

    /**
     * 启动流程
     *
     * @param flowId
     * @return
     */
    @PostMapping("/startFlow/{flowId}")
    public JsonResult startFlow(@PathVariable("flowId") Long flowId) {
        FlowInstance flowInstance = flowInstanceService.startFlow(flowId, getUser());
        return JsonResult.ok(flowNodeExecService.getFlowInstanceAndExec(flowInstance.getId()));
    }

    /**
     * 暂停流程
     *
     * @param flowInstanceId
     * @return
     */
    @PostMapping("/stopFlow/{flowInstanceId}")
    public JsonResult stopFlow(@PathVariable("flowInstanceId") Long flowInstanceId) {
        return JsonResult.ok(flowInstanceService.stopFlow(flowInstanceId));
    }

    /**
     * 流程日志
     *
     * @param flowInstanceId
     * @return
     */
    @GetMapping("/logs/{flowInstanceId}")
    public JsonResult logs(@PathVariable("flowInstanceId") Long flowInstanceId) {
        return JsonResult.ok(flowLogService.getFlowLogByFlowId(flowInstanceId));
    }

    /**
     * 获取流程和节点执行状态
     *
     * @param flowInstanceId
     * @return
     */
    @GetMapping("/getFlowNodeExec/{flowInstanceId}")
    public JsonResult getFlowNodeExec(@PathVariable("flowInstanceId") Long flowInstanceId) {
        return JsonResult.ok(flowNodeExecService.getFlowInstanceAndExec(flowInstanceId));
    }

    /**
     * 校验公式计算的表达式
     *
     * @param expression
     * @return
     */
    @PostMapping("/validateExpression")
    public JsonResult validateExpression(@RequestBody String expression) {
        String originString = Base64.decodeStr(expression);
        JSONObject result = new JSONObject();
        JexlEngine engine = JexlEngineFactory.getInstance();
        try {
            engine.createScript(originString);
            result.put("errMsg", null);
            result.put("valid", true);
        } catch (Exception exception) {
            result.put("errMsg", exception.getMessage());
            result.put("valid", false);
        }
        return JsonResult.ok(result);
    }
}
